package com.quan.api.ums;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.quan.commons.core.bean.R;
import com.quan.commons.core.biz.support.MyBaseController;
import com.quan.commons.core.exception.BizException;
import com.quan.commons.core.utils.*;
import com.quan.commons.tools.sms.ALiYunSMSTools;
import com.quan.mall.commons.vo.OmsOrderVo;
import com.quan.mall.commons.vo.UmsMemberCouponsVo;
import com.quan.mall.commons.vo.UmsMemberVo;
import com.quan.mall.entity.FmsMemberWallet;
import com.quan.mall.entity.UmsMember;
import com.quan.mall.entity.UmsMemberLevel;
import com.quan.mall.service.FmsMemberWalletService;
import com.quan.mall.service.UmsMemberLevelService;
import com.quan.mall.service.UmsMemberService;
import com.quan.system.entity.SysUser;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 会员
 *
 * @author yhaoquan
 * @email yhaoquan@163.com
 * @date 2021-03-08 21:41:30
 */
@Slf4j
@Api(tags = "会员")
@RestController
@RequestMapping("/api/mall/umsmember")
public class ApiUmsMemberController extends MyBaseController {

    @Autowired
    private UmsMemberService service;

    @Autowired
    private RedisUtils redisOperator;

    @Autowired
    private ALiYunSMSTools smsTools;

    @Autowired
    private FmsMemberWalletService fmsMemberWalletService;

    @Autowired
    private UmsMemberLevelService umsMemberLevelService;

    /**
     * 会员登录
     * @param vo
     * @return
     */
    @PostMapping("/login")
    public Object login(@RequestBody UmsMemberVo vo) {
        if(StringUtils.isBlank(vo.getMobile())) {
            return R.failure("手机号码不能为空");
        }

        if(StringUtils.isBlank(vo.getPassword())) {
            return R.failure("密码不能为空");
        }

        final UmsMember member = this.service.getMemberByMobile(vo.getMobile());

        // 判断用户是否存在
        if(null == member) {
            return R.failure("账号不存在");
        }
        // 验证密码是否正确
        if (!PasswordUtils.isPasswordValid(member.getPassword(), vo.getPassword(), member.getSecret())) {
            return R.failure("登录失败，账号或密码不正确！");
        }
        // 判断用户账号状态
        if (member.getStatus() == 0) {
            return R.failure("账号已锁定，请联系客服！");
        }

        return R.ok().put("data", member);
    }

    /**
     * 创建账号
     * @param vo
     * @return
     */
    @PostMapping("/register")
    public Object register(@RequestBody UmsMemberVo vo) {
        // 获取验证码进行比对
        String smsCode = this.redisOperator.get("mall:register:code:" + vo.getMobile());
        if (null == smsCode) {
            return R.failure("验证码过期，请重新获取");
        }
        if (!smsCode.equals(vo.getValidCode())) {
            return R.failure("验证码不正确");
        }

        final boolean mobile = this.service.hasExist("mobile", vo.getMobile(), UmsMember.class);
        if(mobile) {
            return R.failure("该手机号已存在");
        }

        this.service.saveMember(vo);

        final UmsMemberLevel level = this.umsMemberLevelService.getById(vo.getLevelId());
        vo.setLevel(level);


        return R.ok().put("data", vo);
    }

    /**
     * 创建账号
     * @param vo
     * @return
     */
    @PostMapping("/resetPassword")
    public Object resetPassword(@RequestBody UmsMemberVo vo) {
        // 获取验证码进行比对
        String smsCode = this.redisOperator.get("mall:forget:code:" + vo.getMobile());
        if (null == smsCode) {
            return R.failure("验证码过期，请重新获取");
        }
        if (!smsCode.equals(vo.getValidCode())) {
            return R.failure("验证码不正确");
        }

        final UmsMember memberByMobile = this.service.getMemberByMobile(vo.getMobile());
        final String serc = RandomUitl.uuid();
        memberByMobile.setSecret(serc);
        memberByMobile.setPassword(PasswordUtils.encodePassword(vo.getPassword(), serc));

        this.service.updateById(memberByMobile);

        return R.ok().put("data", memberByMobile);
    }

    /**
     * 发送短信验证码
     * @param mobile
     * @return
     */
    @GetMapping("/sendSmsCode")
    public Object sendSmsCode(String mobile) {
        try {
            // 验证码
            String smsCode = RandomUitl.generateInteger(4);

            // 发送
            Map<String, Object> content = new HashMap<String, Object>();
            content.put("code", smsCode);
            boolean b = this.smsTools.baseSMSSend(mobile, content);

            if (b) {
                // 将会员验证码存放到Redis缓存中，有效时间为10秒
                this.redisOperator.set("mall:register:code:" + mobile, smsCode, 1000);

                return R.ok();
            } else {
                return R.failure();
            }
        } catch (Exception e) {
            return R.failure("短信发送失败");
        }
    }

    /**
     * 发送短信验证码
     * @param mobile
     * @return
     */
    @GetMapping("/sendSmsCodeForget")
    public Object sendSmsCodeForget(String mobile) {
        try {
            if(!this.service.hasExist("mobile", mobile, UmsMember.class)) {
                return R.failure("该手机号不存在");
            }

            // 验证码
            String smsCode = RandomUitl.generateInteger(4);

            // 发送
            Map<String, Object> content = new HashMap<String, Object>();
            content.put("code", smsCode);
            boolean b = this.smsTools.baseSMSSend(mobile, content);

            if (b) {
                // 将会员验证码存放到Redis缓存中，有效时间为10秒
                this.redisOperator.set("mall:forget:code:" + mobile, smsCode, 1000);

                return R.ok();
            } else {
                return R.failure();
            }
        } catch (Exception e) {
            return R.failure("短信发送失败");
        }
    }


    /**
     * 根据OPENID获取会员信息
     * @param openid
     * @return
     */
    @GetMapping("/getUserInfo/{openid}")
    public R getUserByOpenId(@PathVariable String openid) {
        UmsMember umsMember = this.service.getMemberByOpenId(openid);
        return R.ok().put("data", umsMember);
    }

    /**
     * 根据ID获取会员信息
     * @param id
     * @return
     */
    @GetMapping("/getUserById/{id}")
    public R getUserById(@PathVariable String id) {
        UmsMember umsMember = this.service.getById(id);
        System.out.println(umsMember);
        return R.ok().put("data", umsMember);
    }


    /**
     * 根据手机号获取会员信息
     * @param mobile
     * @return
     */
    @GetMapping("/getUserByMobile/{mobile}")
    public R getUserByMobile(@PathVariable String mobile) {
        UmsMember umsMember = this.service.getMemberByMobile(mobile);
        return R.ok().put("data", umsMember);
    }

    /**
     * 会员升级，生成支付订单号，将升级信息保存到缓存中，用于支付回调获取，进行会员升级
     * @param memberId 会员ID
     * @param levelId 级别ID
     * @return
     */
    @GetMapping("/upgradeMemberPrep")
    public R upgradeMember(@RequestParam(value = "memberId") Long memberId,
                            @RequestParam(value = "levelId") Long levelId) {

        final String sn = OrderUtils.getSN();
        Map<String, Object> map = new HashMap<String, Object>();
        //升级的会员ID
        map.put("memberId", memberId);
        //升级的级别ID
        map.put("levelId", levelId);

        // 将会员升级信息存放到Redis缓存中，有效时间为30分钟
        this.redisOperator.set("mall:member:upgrade:" + sn, JSON.toJSONString(map), 60 * 30);

        return R.ok().put("data", sn);
    }


    /**
     * 我的推荐
     * @param memberId
     * @return
     */
    @GetMapping("/myCecommend")
    public R myCecommend(@RequestParam(value = "memberId") Long memberId) {

        UmsMemberVo vo = this.service.getMyCecommend(memberId);

        return R.ok().put("data", vo);
    }


    /**
     * 获取我的钱包
     * @param memberId
     * @return
     */
    @GetMapping("/getMyWallter")
    public R getMyWallter(@RequestParam(value = "memberId") Long memberId) {

        UmsMemberVo vo = this.service.getMyWallter(memberId);

        return R.ok().put("data", vo);
    }

    /**
     * 我的分销记录
     * @param vo
     * @return
     */
    @GetMapping(value = "getMyDistribution")
    public R getMyDistribution(OmsOrderVo vo) {
        PageUtils page = this.service.getMyDistribution(new PageUtils(request), vo);
        return R.ok().put("data", page);
    }

    /**
     * 获取用户优惠券
     * @param memberId
     * @return
     */
    @GetMapping(value = "/getUserCoupons/{memberId}")
    public R getUserCoupons(@PathVariable Long memberId) {
        List<UmsMemberCouponsVo> list = this.service.getUserCoupons(memberId);
        return R.ok().put("data", list);
    }

}
